import * as Blockly from 'blockly/core';
import { JavascriptGenerator, javascriptGenerator } from "blockly/javascript";
import { Tanslate } from './translate';
import { getValue } from './com';
import { WorkspaceSvg } from 'blockly/core';
export namespace Loops {
    const blocks = [
        {
            'key': 'controls_flow_index',
            'message0': '%{controls_flow_index}',
            'style': 'loop_blocks',
            "output": "Number",
        },
        {
            'key': 'controls_repeat_ext',
            'message0': '%{BKY_CONTROLS_REPEAT_TITLE}',
            'args0': [
                {
                    'type': 'input_value',
                    'name': 'TIMES',
                    'check': 'Number',
                },
            ],
            'message1': '%{BKY_CONTROLS_REPEAT_INPUT_DO} %1',
            'args1': [
                {
                    'type': 'input_statement',
                    'name': 'DO',
                },
            ],
            'previousStatement': null,
            'nextStatement': null,
            'style': 'loop_blocks',
            'tooltip': '%{BKY_CONTROLS_REPEAT_TOOLTIP}',
            'helpUrl': '%{BKY_CONTROLS_REPEAT_HELPURL}',
        },
        {
            'key': 'controls_repeat',
            'message0': '%{BKY_CONTROLS_REPEAT_TITLE}',
            'args0': [
                {
                    'type': 'field_number',
                    'name': 'TIMES',
                    'value': 10,
                    'min': 0,
                    'precision': 1,
                },
            ],
            'message1': '%{BKY_CONTROLS_REPEAT_INPUT_DO} %1',
            'args1': [
                {
                    'type': 'input_statement',
                    'name': 'DO',
                },
            ],
            'previousStatement': null,
            'nextStatement': null,
            'style': 'loop_blocks',
            'tooltip': '%{BKY_CONTROLS_REPEAT_TOOLTIP}',
            'helpUrl': '%{BKY_CONTROLS_REPEAT_HELPURL}',
        },
        {
            'key': 'controls_whileUntil',
            'message0': '%1 %2',
            'args0': [
                {
                    'type': 'field_dropdown',
                    'name': 'MODE',
                    'options': [
                        ['%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_WHILE}', 'WHILE'],
                        ['%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_UNTIL}', 'UNTIL'],
                    ],
                },
                {
                    'type': 'input_value',
                    'name': 'BOOL',
                    'check': 'Boolean',
                },
            ],
            'message1': '%{BKY_CONTROLS_REPEAT_INPUT_DO} %1',
            'args1': [
                {
                    'type': 'input_statement',
                    'name': 'DO',
                },
            ],
            'previousStatement': null,
            'nextStatement': null,
            'style': 'loop_blocks',
            'helpUrl': '%{BKY_CONTROLS_WHILEUNTIL_HELPURL}',
        },
        {
            'key': 'controls_forEach',
            'message0': '%{BKY_CONTROLS_FOREACH_TITLE}',
            'args0': [
                {
                    'type': 'field_variable',
                    'name': 'VAR',
                    "variable": "item"
                },
                {
                    'type': 'input_value',
                    'name': 'LIST',
                    'check': 'Array',
                },
            ],
            'message1': '%{BKY_CONTROLS_REPEAT_INPUT_DO} %1',
            'args1': [
                {
                    'type': 'input_statement',
                    'name': 'DO',
                },
            ],
            'previousStatement': null,
            'nextStatement': null,
            'style': 'loop_blocks',
            'helpUrl': '%{BKY_CONTROLS_FOREACH_HELPURL}'
        },
        {
            'key': 'controls_flow_statements',
            'message0': '%1',
            'args0': [
                {
                    'type': 'field_dropdown',
                    'name': 'FLOW',
                    'options': [
                        ['%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK}', 'break'],
                        ['%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE}', 'continue'],
                    ],
                },
            ],
            'previousStatement': null,
            'style': 'loop_blocks',
            'suppressPrefixSuffix': true
        },
    ]

    export function init() {
        initGenerator()
        Tanslate.tr(blocks).forEach((item: any) => {
            Blockly.Blocks[item.key] = {
                init: function (this: Blockly.Block) {
                    this.jsonInit(item);
                    if (item.key === 'controls_flow_statements') {
                        this.setOnChange((e) => {
                            const ws = this.workspace as WorkspaceSvg;
                            if (
                                !ws.isDragging ||
                                ws.isDragging() ||
                                (e.type !== Blockly.Events.BLOCK_MOVE && e.type !== Blockly.Events.BLOCK_CREATE)
                            ) {
                                return;
                            }
                            this.setWarningText(
                                Blockly.Msg['CONTROLS_FLOW_STATEMENTS_WARNING'],
                            );
                        })
                    }
                }
            }
        })
    }

    export function getTools() {
        const netBlocks = {
            kind: 'category',
            name: Blockly.Msg['loops'],
            "colour": 120,
            contents: [] as any[]
        }
        blocks.forEach((item: any) => {
            netBlocks.contents.push({
                kind: 'block',
                type: item.key
            })
        })

        return netBlocks
    }
    const FLOW_INDEX = 'sd_flow_index'
    function initGenerator() {
        javascriptGenerator.forBlock['controls_flow_index'] = function () {
            return FLOW_INDEX;
        }
        javascriptGenerator.forBlock['controls_repeat_ext'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const body = block.getInputTargetBlock('DO');
            const TIMES = getValue(block, generator, 'TIMES')
            let lines = ''
            if (body) {
                const line = generator.blockToCode(body)
                lines = (typeof line === 'string' ? line : line.join('\n'))
            }
            if (!TIMES) {
                throw new Error(block.id);
            }
            return `for (let ${FLOW_INDEX} = 0; ${FLOW_INDEX} < ${TIMES}; ${FLOW_INDEX}++) {\n${lines}\n}\n`;
        }

        javascriptGenerator.forBlock['controls_repeat'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const body = block.getInputTargetBlock('DO');
            const TIMES = getValue(block, generator, 'TIMES')
            let lines = ''
            if (body) {
                const line = generator.blockToCode(body)
                lines = (typeof line === 'string' ? line : line.join('\n'))
            }
            if (!TIMES) {
                throw new Error(block.id);
            }
            return `for (let ${FLOW_INDEX} = 0; ${FLOW_INDEX} < ${TIMES}; ${FLOW_INDEX}++) {\n${lines}\n}\n`;
        }

        javascriptGenerator.forBlock['controls_whileUntil'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const body = block.getInputTargetBlock('DO');
            const MODE = getValue(block, generator, 'MODE')
            const BOOL = getValue(block, generator, 'BOOL')
            let lines = ''
            if (body) {
                const line = generator.blockToCode(body)
                lines = (typeof line === 'string' ? line : line.join('\n'))
            }
            if (!BOOL) {
                throw new Error(block.id);
            }
            return `while (${MODE === 'WHILE' ? '' : '!'}${BOOL}) {\n${lines}\n}\n`;
        }

        javascriptGenerator.forBlock['controls_forEach'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const body = block.getInputTargetBlock('DO');
            const VAR = getValue(block, generator, 'VAR')
            const LIST = getValue(block, generator, 'LIST')
            let lines = ''
            if (body) {
                const line = generator.blockToCode(body)
                lines = (typeof line === 'string' ? line : line.join('\n'))
            }
            if (!VAR || !LIST) {
                throw new Error(block.id);
            }
            return `for (const ${VAR} of ${LIST}) {\n${lines}\n}\n`;
        }

        javascriptGenerator.forBlock['controls_flow_statements'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const value = getValue(block, generator, 'FLOW')
            return `${value}`;
        }
    }
}